import { Component, OnInit, OnDestroy, ChangeDetectionStrategy, ChangeDetectorRef, Directive, ElementRef, Renderer2, Injectable, NgZone } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { NzButtonModule } from 'ng-zorro-antd/button';
import { NzAlertModule } from 'ng-zorro-antd/alert';
import { NzGridModule } from 'ng-zorro-antd/grid';
import { NzTagModule } from 'ng-zorro-antd/tag';
import { NzFormModule } from 'ng-zorro-antd/form';
import { NzMessageService } from 'ng-zorro-antd/message';
import { NzIconModule } from 'ng-zorro-antd/icon';
import * as XLSX from 'xlsx';
import { DomTrackingService } from './dom-tracking.service'
import { setStrategyType, getStrategyType } from '../../utils/keyTypeStore'
import { KeyStrategyDisplayComponent } from '../../components/key-strategy-display/key-strategy-display.component'

@Component({
  selector: 'app-inventory-list',
  standalone: true,
  imports: [
    CommonModule,
    FormsModule,
    NzButtonModule,
    NzAlertModule,
    NzGridModule,
    NzTagModule,
    NzFormModule,
    NzIconModule,
    KeyStrategyDisplayComponent
  ],
  templateUrl: './inventory-list.component.html',
  styleUrls: ['./inventory-list.component.less'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class InventoryListComponent implements OnInit, OnDestroy {
  keyType: string = 'id';
  books: any[] = [];
  academicBooks: any[] = [];
  nextId: number = 1;
  renderTime: string | null = null;
  showAcademicTestList: boolean = false;
  loading: boolean = false;
  totalOperations: number = 0;
  lastOperationTime: string = '0';

  constructor(
    private message: NzMessageService,
    private cdr: ChangeDetectorRef,
    private domTrackingService: DomTrackingService,

    private ngZone: NgZone
  ) {
    this.keyType = getStrategyType() || 'none'
  }




  private randomNum(min: number, max: number): number {
    return Math.floor(Math.random() * (max - min + 1)) + min;
  }


  private generateUniqueId(): string {
    return `BOOK_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
  }



  generateMockBook(): any {
    const realTitles = [
      '百年孤独', '1984', '动物农场', '小王子', '围城', '活着', '三体', '人类简史', '情商', '影响力',
      '乌合之众', '君主论', '资治通鉴', '红楼梦', '西游记', '水浒传', '三国演义', '呐喊', '朝花夕拾', '边城'
    ];
    const realAuthors = [
      '加西亚·马尔克斯', '乔治·奥威尔', '安托万·德·圣-埃克苏佩里', '钱钟书', '余华', '刘慈欣', '尤瓦尔·赫拉利', '丹尼尔·戈尔曼', '古斯塔夫·勒庞', '尼科洛·马基雅维利',
      '司马光', '曹雪芹', '吴承恩', '施耐庵', '罗贯中', '鲁迅', '沈从文'
    ];
    const realPublishers = [
      '新经典文化', '上海译文出版社', '人民文学出版社', '北京十月文艺出版社', '重庆出版社',
      '中信出版集团', '浙江人民出版社', '商务印书馆', '译林出版社', '南海出版公司'
    ];
    const descriptions = [
      '本书详细介绍了相关技术原理与实践。',
      '适合初学者和进阶开发者阅读。',
      '内容涵盖理论与实战案例。',
      '帮助读者快速掌握核心知识。'
    ];
    return {
      id: Date.now(),
      title: realTitles[Math.floor(Math.random() * realTitles.length)],
      author: realAuthors[Math.floor(Math.random() * realAuthors.length)],
      status: '在架',
      expanded: false,
      isbn: '978' + Math.floor(1000000000 + Math.random() * 9000000000),
      publisher: realPublishers[Math.floor(Math.random() * realPublishers.length)],
      publishDate: `202${Math.floor(Math.random() * 4 + 1)}-0${Math.floor(Math.random() * 9 + 1)}-15`,
      description: descriptions[Math.floor(Math.random() * descriptions.length)],
      price: (Math.random() * 100 + 20).toFixed(2),
      rating: (Math.random() * 2 + 3).toFixed(1)
    };
  }

  generateBook(): any {
    const titles = [
      '深入理解Vue.js', 'JavaScript权威指南', '算法导论', '代码整洁之道', '设计模式',
      'Python编程快速上手', 'Java核心技术', 'MySQL必知必会', 'Redis设计与实现', '计算机网络',
      '操作系统概念', '数据结构与算法分析', '编译原理', '软件工程', '人工智能基础',
      'React技术栈', 'Node.js实战', 'Docker容器化', 'Kubernetes实践', '微服务架构'
    ];
    const authors = ['张明华', '李晓东', '王建国', '赵丽娟', '陈思远', '刘志强', '杨雪梅', '郑昊然'];
    const categories = ['计算机技术', '编程语言', '算法与数据结构', '数据库', '网络技术', '人工智能', '软件工程'];
    const statuses = ['正常', '缺货', '预警', '补货中'];
    const locations = ['A-01', 'A-02', 'B-01', 'B-02', 'C-01', 'C-02', 'D-01', 'D-02'];

    const colors = ['#3498db', '#2ecc71', '#e74c3c', '#f1c40f', '#9b59b6', '#1abc9c', '#e67e22'];

    return {
      id: this.generateUniqueId(),
      title: titles[this.randomNum(0, titles.length - 1)],
      author: authors[this.randomNum(0, authors.length - 1)],
      category: categories[this.randomNum(0, categories.length - 1)],
      status: statuses[this.randomNum(0, statuses.length - 1)],
      stock: this.randomNum(0, 100),
      location: locations[this.randomNum(0, locations.length - 1)],
      isbn: `978${this.randomNum(1000000000, 9999999999)}`,
      coverColor: colors[this.randomNum(0, colors.length - 1)]
    };
  }












  sortBooks(): void {
    const startTime = performance.now();

    this.books = [...this.books.sort((a, b) => {
      if (a.category !== b.category) {
        return a.category.localeCompare(b.category);
      }
      if (a.author !== b.author) {
        return a.author.localeCompare(b.author);
      }
      return a.title.localeCompare(b.title);
    })];
    this.totalOperations++;
    this.lastOperationTime = (performance.now() - startTime).toFixed(2);
    this.cdr.detectChanges();
  }

  insertRandomBook(): void {
    const startTime = performance.now();
    const randomIndex = Math.floor(Math.random() * (this.books.length + 1));
    this.books.splice(randomIndex, 0, this.generateBook());
    this.books = [...this.books];
    this.totalOperations++;
    this.lastOperationTime = (performance.now() - startTime).toFixed(2);
    this.cdr.detectChanges();
  }

  deleteRandomBook(): void {
    if (this.books.length === 0) return;
    const startTime = performance.now();
    const randomIndex = Math.floor(Math.random() * this.books.length);
    this.books.splice(randomIndex, 1);
    this.books = [...this.books];
    this.totalOperations++;
    this.lastOperationTime = (performance.now() - startTime).toFixed(2);
    this.cdr.detectChanges();
  }

  replaceAllBooks(): void {
    const startTime = performance.now();
    this.books = Array.from({ length: this.books.length }, () => this.generateBook());
    this.totalOperations++;
    this.lastOperationTime = (performance.now() - startTime).toFixed(2);
    this.cdr.detectChanges();
  }


  get reuseRate(): string {
    const N = this.academicBooks.length;
    if (N === 0) return '0.00';


    const reusedCount = N - this.domTrackingService.destroyed;
    return (reusedCount >= 0 && N > 0 ? (reusedCount / N) * 100 : 0).toFixed(2);
  }


  getStockClass(stock: number): string {
    if (stock === 0) return 'stock-empty';
    if (stock < 10) return 'stock-low';
    return 'stock-normal';
  }


  removeBook(bookId: string): void {
    const index = this.books.findIndex(book => book.id === bookId);
    if (index !== -1) {
      this.books.splice(index, 1);
      this.books = [...this.books];
      this.totalOperations++;
      this.cdr.detectChanges();
    }
  }

  increaseStock(bookId: string): void {
    const book = this.books.find(book => book.id === bookId);
    if (book) {
      book.stock++;
      this.updateBookStatus(book);
      this.totalOperations++;
      this.cdr.detectChanges();
    }
  }

  decreaseStock(bookId: string): void {
    const book = this.books.find(book => book.id === bookId);
    if (book && book.stock > 0) {
      book.stock--;
      this.updateBookStatus(book);
      this.totalOperations++;
      this.cdr.detectChanges();
    }
  }

  private updateBookStatus(book: any): void {
    if (book.stock === 0) {
      book.status = '缺货';
    } else if (book.stock <= 5) {
      book.status = '预警';
    } else if (book.stock > 10) {
      book.status = '正常';
    }
  }


  getStatusType(status: string): string {

    switch (status) {
      case '正常':
        return '#87d068';
      case '缺货':
        return '#f50';
      case '预警':
        return '#2db7f5';
      case '补货中':
        return '#108ee9';
      default:
        return '#108ee9';
    }
  }


  private sleep(ms: number): Promise<void> {
    return new Promise(resolve => setTimeout(resolve, ms));
  }


  trackById(index: number, item: any): any {
    return this.keyType === 'id' ? item.id : index;
  }


  get totalStock(): number {
    return this.books.reduce((sum, book) => sum + book.stock, 0);
  }


  addBook() {
    const newBook = this.generateBook();
    this.books.unshift(newBook);
    this.books = [...this.books];
    this.totalOperations++;
    this.cdr.detectChanges();
  }

  initStock() {
    this.books = Array.from({ length: 10 }).map(() => this.generateBook());
    this.cdr.detectChanges();
  }

  clearStock() {
    this.books.forEach(book => {
      book.stock = 0;
      this.updateBookStatus(book);
    });
    this.cdr.detectChanges();
  }


  toggleKeyType(value: string) {

    this.keyType = value
    setStrategyType(value)
    this.message.info(`已切换到${value}`)
  }


  generateAcademicBooks(count: number): void {
    this.nextId = 1;
    this.academicBooks = Array.from({ length: count }, () => this.generateMockBook());
    this.cdr.detectChanges();
  }

  insertRandomAcademicBook(): void {
    const randomIndex = Math.floor(Math.random() * (this.academicBooks.length + 1));
    this.academicBooks.splice(randomIndex, 0, this.generateMockBook());
    this.academicBooks = [...this.academicBooks];
    this.cdr.detectChanges();
  }

  deleteRandomAcademicBook(): void {
    if (this.academicBooks.length === 0) return;
    const randomIndex = Math.floor(Math.random() * this.academicBooks.length);
    this.academicBooks.splice(randomIndex, 1);
    this.academicBooks = [...this.academicBooks];
    this.cdr.detectChanges();
  }

  shuffleAcademicBooks(): void {
    for (let i = this.academicBooks.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      [this.academicBooks[i], this.academicBooks[j]] = [this.academicBooks[j], this.academicBooks[i]];
    }
    this.academicBooks = [...this.academicBooks];
    this.cdr.detectChanges();
  }

  replaceAllAcademicBooks(): void {
    const len = this.academicBooks.length > 0 ? this.academicBooks.length : 100;
    this.academicBooks = Array.from({ length: len }, () => this.generateMockBook());
    this.cdr.detectChanges();
  }

  appendToEndAcademicBook(): void {
    this.academicBooks.push(this.generateMockBook());
    this.academicBooks = [...this.academicBooks];
    this.cdr.detectChanges();
  }

  insertToMiddleAcademicBook(): void {
    const mid = Math.floor(this.academicBooks.length / 2);
    this.academicBooks.splice(mid, 0, this.generateMockBook());
    this.academicBooks = [...this.academicBooks];
    this.cdr.detectChanges();
  }

  partialUpdateAcademicBook(): void {
    if (this.academicBooks.length === 0) return;
    const idx = Math.floor(Math.random() * this.academicBooks.length);

    this.academicBooks[idx].title = this.academicBooks[idx].title + '_更新';
    this.academicBooks = [...this.academicBooks];
    this.cdr.detectChanges();
  }


  async autoTestReuse(): Promise<any> {
    console.log('autoTestReuse: Starting test...');
    this.domTrackingService.reset();

    this.showAcademicTestList = true;


    this.academicBooks = [];
    this.cdr.detectChanges();
    await this.sleep(100);


    this.academicBooks = Array.from({ length: 100 }, () => this.generateMockBook());
    this.cdr.detectChanges();
    await this.sleep(1000);


    this.domTrackingService.reset();
    console.log('domTrackStats RESET before operation:', { created: this.domTrackingService.created, destroyed: this.domTrackingService.destroyed });

    console.log(`autoTestReuse: Performing operation for keyType: ${this.keyType}...`);
    if (this.keyType === 'id') {
      this.shuffleAcademicBooks();
      console.log('Operation: shuffleAcademicBooks (for ID keys)');
    } else {
      const currentLength = this.academicBooks.length;
      this.academicBooks = [];
      this.cdr.detectChanges();
      await this.sleep(200);

      this.academicBooks = Array.from({ length: currentLength }, () => this.generateMockBook());
      console.log('Operation: replaceAllBooks (for Index/None keys)');
    }

    this.cdr.detectChanges();
    await this.sleep(5000);

    const createdDuringOperation = this.domTrackingService.created;
    const destroyedDuringOperation = this.domTrackingService.destroyed;

    this.showAcademicTestList = false;
    this.cdr.detectChanges();
    await this.sleep(500);

    const N = this.academicBooks.length;
    const reusedCalculated = N - destroyedDuringOperation;
    const reuseRatePercentageCalculated = (reusedCalculated >= 0 && N > 0 ? (reusedCalculated / N) * 100 : 0).toFixed(2);

    const stats = {
      created: createdDuringOperation,
      reused: reusedCalculated,
      destroyed: destroyedDuringOperation,
      reuseRate: reuseRatePercentageCalculated,
      totalItems: N
    };

    this.domTrackStats.created = stats.created;
    this.domTrackStats.destroyed = stats.destroyed;
    this.domTrackStats.reused = stats.reused;
    this.cdr.detectChanges();

    console.log('autoTestReuse: Test finished. Stats (for current operation):', stats);
    this.message.success('单次自动测试完成！');
    return stats;
  }

  async autoTestBatchAndExportExcel(): Promise<void> {
    const testCases = [
      { name: 'ID作为Key', keyType: 'id' },
      { name: 'Index作为Key', keyType: 'index' },
      { name: '无Key', keyType: 'none' }
    ];

    const results: any[] = [];
    const operations = [
      { name: '生成100本', fn: (count = 100) => this.generateAcademicBooks(count), isGenerate: true },
      { name: '生成1000本', fn: (count = 1000) => this.generateAcademicBooks(count), isGenerate: true },
      { name: '打乱顺序', fn: () => this.shuffleAcademicBooks(), isGenerate: false },
      { name: '插入元素', fn: () => this.insertRandomAcademicBook(), isGenerate: false },
      { name: '删除元素', fn: () => this.deleteRandomAcademicBook(), isGenerate: false },
      { name: '替换所有', fn: () => this.replaceAllAcademicBooks(), isGenerate: false },
      { name: '尾部追加', fn: () => this.appendToEndAcademicBook(), isGenerate: false },
      { name: '中间插入', fn: () => this.insertToMiddleAcademicBook(), isGenerate: false },
      { name: '局部更新', fn: () => this.partialUpdateAcademicBook(), isGenerate: false }
    ];

    for (const testCase of testCases) {
      this.message.info(`开始测试: ${testCase.name}`);

      for (const operation of operations) {

        const opFn = operation.isGenerate
          ? () => operation.fn(parseFloat(operation.name.replace('生成', '').replace('本', '')))
          : operation.fn;

        const data = await this.performAcademicBookOperationAndMeasure(testCase.keyType, operation.name, opFn);
        results.push(data);

        await this.sleep(500);
      }
    }

    const wb = XLSX.utils.book_new();
    const ws = XLSX.utils.json_to_sheet(results);

    const colWidths = [
      { wch: 15 },
      { wch: 15 },
      { wch: 15 },
      { wch: 15 },
      { wch: 15 },
      { wch: 15 },
      { wch: 15 },
      { wch: 15 },
      { wch: 15 },
      { wch: 20 }
    ];
    ws['!cols'] = colWidths;

    XLSX.utils.book_append_sheet(wb, ws, 'DOM性能测试结果');

    const fileName = `DOM性能测试结果_${new Date().toISOString().slice(0, 19).replace(/[:]/g, '-')}.xlsx`;
    XLSX.writeFile(wb, fileName);

    this.message.success('测试完成，数据已导出到Excel文件');
  }


  async performAcademicBookOperationAndMeasure(keyType: string, operationName: string, operationFn: () => void): Promise<any> {
    console.log(`performAcademicBookOperationAndMeasure: Starting test for KeyType: ${keyType}, Operation: ${operationName}`);


    this.showAcademicTestList = true;
    this.renderTime = null;


    this.academicBooks = [];
    this.cdr.detectChanges();
    await this.sleep(50);

    this.domTrackingService.reset();

    const totalTimeStart = performance.now();


    if (!operationName.startsWith('生成')) {
      this.generateAcademicBooks(500);
      this.cdr.detectChanges();
      await this.sleep(50);
      this.domTrackingService.reset();
    }

    const renderTime = await this.measureOperation(operationFn);
    const totalTime = (performance.now() - totalTimeStart).toFixed(2);

    const createdCount = this.domTrackingService.created;
    const destroyedCount = this.domTrackingService.destroyed;
    const currentAcademicListLength = this.academicBooks.length;


    const reusedCount = currentAcademicListLength - destroyedCount;
    const reuseRatePercentage = (reusedCount >= 0 && currentAcademicListLength > 0 ? (reusedCount / currentAcademicListLength) * 100 : 0).toFixed(2);

    this.domTrackStats.created = createdCount;
    this.domTrackStats.destroyed = destroyedCount;
    this.domTrackStats.reused = reusedCount;
    this.cdr.detectChanges();

    return {
      '测试类型': keyType,
      '操作类型': operationName,
      '渲染时间(ms)': renderTime,
      '总耗时(ms)': totalTime,
      'DOM创建数': createdCount,
      'DOM复用数': reusedCount,
      'DOM销毁数': destroyedCount,
      'DOM复用率(%)': reuseRatePercentage,
      '列表项数量': currentAcademicListLength,
      '测试时间': new Date().toLocaleString()
    };
  }

  async exportReuseStatsToExcel() {

    const stats = [{
      created: this.domTrackingService.created,
      reused: this.domTrackingService.reused,
      destroyed: this.domTrackingService.destroyed,
      reuseRate: this.reuseRate + '%',
      time: new Date().toLocaleString()
    }];

    const currentTotalItems = this.academicBooks.length;
    const currentReused = currentTotalItems - this.domTrackingService.destroyed;
    stats[0].reused = currentReused;

    const ws = XLSX.utils.json_to_sheet(stats);
    const wb = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(wb, ws, '复用统计');
    XLSX.writeFile(wb, `reuse-stats-${Date.now()}.xlsx`);
    this.message.success('统计数据已导出为Excel！');



































  }



  async measureOperation(operationFn: () => void): Promise<string> {
    return new Promise(resolve => {
      this.ngZone.runOutsideAngular(() => {
        requestAnimationFrame(() => {
          performance.clearMarks();
          performance.clearMeasures();
          performance.mark('op-start');

          operationFn();


          setTimeout(() => {
            requestAnimationFrame(() => {
              performance.mark('op-end');
              performance.measure('op-duration', 'op-start', 'op-end');
              const measure = performance.getEntriesByName('op-duration')[0];
              const duration = measure ? measure.duration.toFixed(2) : '0.00';
              this.ngZone.run(() => {
                this.renderTime = duration;
                this.cdr.detectChanges();
                resolve(duration);
              });
            });
          }, 0);
        });
      });
    });
  }


  get domTrackStats(): { created: number; destroyed: number; reused: number } {




    const N = this.academicBooks.length;
    const destroyedCount = this.domTrackingService.destroyed;
    const reusedCount = N - destroyedCount;

    return {
      created: this.domTrackingService.created,
      destroyed: this.domTrackingService.destroyed,
      reused: reusedCount >= 0 ? reusedCount : 0
    };
  }

  ngOnInit(): void {
    this.books = Array.from({ length: 100 }, () => this.generateBook());
    this.domTrackingService.incrementCreated();
  }

  ngOnDestroy(): void {
    this.domTrackingService.incrementDestroyed();
  }



}
